﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace NumberedTextBoxLib
{
    partial class NumberedTextBox
    {
        /// Required designer variable.
        private System.ComponentModel.IContainer components = null;

        /// Clean up any resources being used.
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        /// Required method for Designer support - do not modify 
        /// the contents of this method with the code editor.
        private void InitializeComponent()
        {
            this.editBox = new System.Windows.Forms.RichTextBox();
            this.SuspendLayout();
            // 
            // editBox
            // 
            this.editBox.AcceptsTab = true;
            this.editBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.editBox.Location = new System.Drawing.Point(27, 3);
            this.editBox.Name = "editBox";
            this.editBox.Size = new System.Drawing.Size(122, 117);
            this.editBox.TabIndex = 0;
            this.editBox.Text = "";
            this.editBox.WordWrap = false;
            // 
            // NumberedTextBox
            // 
            this.Controls.Add(this.editBox);
            this.Name = "NumberedTextBox";
            this.Size = new System.Drawing.Size(152, 123);
            this.ResumeLayout(false);
            editBox.ForeColor = Color.Blue;
            this.Font = new Font(this.Font, FontStyle.Bold);
        }

        private System.Windows.Forms.RichTextBox editBox;
    }

    public partial class NumberedTextBox : UserControl
    {
        private int lineIndex = 0;

        new public String Text
        {
            get
            {
                return editBox.Text;
            }
            set
            {
                editBox.Text = value;
            }
        }

        public string[] Lines
        {
            get { return Regex.Split(this.Text, "\n"); }
        }

        public NumberedTextBox()
        {
            InitializeComponent();
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
            editBox.Font = new Font("Courier New",10, FontStyle.Bold);
            editBox.SelectionChanged += new EventHandler(selectionChanged);
            editBox.AcceptsTab = true;
            editBox.VScroll += new EventHandler(OnVScroll);
        }

        private void selectionChanged(object sender, EventArgs args)
        {
            FindLine();
            Invalidate();
        }

        private void FindLine()
        {
            int charIndex = editBox.GetCharIndexFromPosition(new Point(0, 0));
            lineIndex = editBox.GetLineFromCharIndex(charIndex);
        }

        private void DrawLines(Graphics g)
        {
            int counter, y;
            g.Clear(BackColor);
            counter = lineIndex + 1;
            y = 2;
            int max = 0;
            while (y < ClientRectangle.Height - 15)
            {
                SizeF size = g.MeasureString(counter.ToString(), Font);
                g.DrawString(counter.ToString(), Font, new SolidBrush(ForeColor), new Point(3, y));
                counter++;
                y += (int)size.Height;
                if (max < size.Width)
                {
                    max = (int)size.Width;
                }
            }
            max += 6;
            editBox.Location = new Point(max, 0);
            editBox.Size = new Size(ClientRectangle.Width - max, ClientRectangle.Height);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            DrawLines(e.Graphics);
            e.Graphics.TranslateTransform(50, 0);
            editBox.Invalidate();
            base.OnPaint(e);
        }

        ///Redraw the numbers when the editor is scrolled vertically
        private void OnVScroll(object sender, EventArgs e)
        {
            FindLine();
            Invalidate();
        }

    }
}